package com.erp.erp_ui.warehouse.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.erp.enums.ModuleTypeEnum;
import com.erp.enums.OperationStatusEnum;
import com.erp.erp_entitys.business.entity.*;
import com.erp.erp_entitys.business.req.ImportCarryDetailInfoReq;
import com.erp.erp_entitys.warehouse.entity.*;
import com.erp.erp_entitys.warehouse.req.PlanInStoreStatistics1Req;
import com.erp.erp_entitys.warehouse.req.SellOutStockInfoByPageReq;
import com.erp.erp_entitys.warehouse.req.sellOutStockStatistics1Req;
import com.erp.erp_entitys.warehouse.rsp.ImportCarryProductOfOutStockRsp;
import com.erp.erp_entitys.warehouse.rsp.PlanInStoreStatistics1Rsp;
import com.erp.erp_entitys.warehouse.rsp.sellOutStockStatistics1Rsp;
import com.erp.erp_servers.business.ICarryDetailProductService;
import com.erp.erp_servers.business.ICarryDetailService;
import com.erp.erp_servers.warehouse.*;
import com.erp.erp_ui.money.req.OperationReq;
import com.erp.erp_ui.warehouse.enums.DataIsValidEnum;
import com.erp.erp_ui.warehouse.enums.DataSourceTitleEnum;
import com.erp.erp_ui.warehouse.enums.OutStockTypeEnum;
import com.erp.erp_ui.warehouse.req.*;
import com.erp.erp_ui.warehouse.vo.*;
import com.erp.utils.DateUtils;
import com.erp.utils.R;
import com.erp.utils.ResultStatusEnum;
import com.erp.utils.StringUtil;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName : SellOutStockService
 * @Description : 销售出库业务逻辑层
 * @Author : lst
 * @Date: 2020-08-17 19:30
 */
@Service
public class SellOutStockService {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SellOutStockService.class);

    /**
     * 销售出库接口
     */
    private final ISellOutStockService sellOutStockService;

    /**
     * 销售出库明细接口
     */
    private final ISellOutStockDetailService sellOutStockDetailService;

    /**
     * 库存接口
     */
    private final IStockService stockService;

    /**
     * 库存明细接口
     */
    private final IStockDetailService stockDetailService;

    /**
     * 出运明细接口
     */
    private final ICarryDetailService carryDetailService;

    /**
     * 出运明细产品接口
     */
    private final ICarryDetailProductService carryDetailProductService;

    /**
     * 附件接口
     */
    private final IAnnexService annexService;

    /**
     * 临时附件接口
     */
    private final ITempAnnexService tempAnnexService;

    @Autowired
    public SellOutStockService(ISellOutStockService sellOutStockService,
                               ISellOutStockDetailService sellOutStockDetailService,
                               IStockService stockService,
                               IStockDetailService stockDetailService,
                               ICarryDetailService carryDetailService,
                               ICarryDetailProductService carryDetailProductService,
                               IAnnexService annexService,
                               ITempAnnexService tempAnnexService) {
        this.sellOutStockService = sellOutStockService;
        this.sellOutStockDetailService = sellOutStockDetailService;
        this.stockService = stockService;
        this.stockDetailService = stockDetailService;
        this.carryDetailService = carryDetailService;
        this.carryDetailProductService = carryDetailProductService;
        this.annexService = annexService;
        this.tempAnnexService = tempAnnexService;
    }

    /**
     * 分页查询
     * @param req 查询参数
     * @return 分页信息
     */
    public PageInfo<SellOutStockPageInfoVo> getListByPage(SellOutStockInfoByPageReq req){
        //调用接口查询结果
        List<SellOutStockEntity> contractList = sellOutStockService.getListByPage(req);
        PageInfo pageInfo = new PageInfo(contractList);
        //初始化回参对象集合
        List<SellOutStockPageInfoVo> voList = new ArrayList<>();
        if(CollectionUtils.isEmpty(contractList)){
            pageInfo.setList(voList);
            return pageInfo;
        }
        for(SellOutStockEntity contract : contractList){
            SellOutStockPageInfoVo vo = new SellOutStockPageInfoVo();
            //赋值
            BeanUtils.copyProperties(contract, vo);
            //出库日期
            vo.setTime(DateUtils.format(contract.getTime()));
            //创建日期
            vo.setCreateDate(DateUtils.format(contract.getCreateDate()));
            //提货日期
            vo.setPickUpDate(DateUtils.format(contract.getPickUpDate()));
            //状态
            vo.setStatusStr(OperationStatusEnum.getDescById(contract.getStatus()));

            voList.add(vo);
        }

        pageInfo.setList(voList);
        return pageInfo;
    }

    /**
     * 导出运明细分页查询
     * @param req 查询条件
     * @return 分页信息
     */
    public PageInfo<ImportCarryDetailOfOutStockVo> getCarryDetailInfo(ImportCarryDetailInfoReq req){
        //初始化回参对象集合
        List<ImportCarryDetailOfOutStockVo> detailVos = new ArrayList<>();
        //调用接口查询结果
        List<CarryDetailEntity> detailRspList = carryDetailService.getImportCarryOfSaleOutStock(req);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(detailRspList);
        if(CollectionUtils.isEmpty(detailRspList)){
            pageInfo.setList(detailVos);
            return pageInfo;
        }
        for(CarryDetailEntity detailRsp : detailRspList){
            //初始化回参对象
            ImportCarryDetailOfOutStockVo detailVo = new ImportCarryDetailOfOutStockVo();
            //字段赋值
            BeanUtils.copyProperties(detailRsp, detailVo);
            //日期处理
            detailVo.setTime(DateUtils.format(detailRsp.getTime()));
            detailVo.setCreateDate(DateUtils.format(detailRsp.getCreateDate()));

            detailVos.add(detailVo);
        }
        pageInfo.setList(detailVos);
        return pageInfo;
    }

    /**
     * 根据出运明细id获取出运明细产品信息
     * @param id 出运明细id
     * @return 出运明细产品信息
     */
    public List<ImportCarryProductOfOutStockVo> getCarryDetailProductList(Integer id){
        //初始化回参对象集合
        List<ImportCarryProductOfOutStockVo> productVos = new ArrayList<>();
        if(null == id){
            return productVos;
        }
        //调用接口获取出运明细产品信息
        List<ImportCarryProductOfOutStockRsp> productList = carryDetailProductService.getImportCarryDetailProductInfo(id);
        if(CollectionUtils.isEmpty(productList)){
            return productVos;
        }
        for(ImportCarryProductOfOutStockRsp product : productList){
            //初始化回参对象实体
            ImportCarryProductOfOutStockVo productVo = new ImportCarryProductOfOutStockVo();
            //字段赋值
            BeanUtils.copyProperties(product, productVo);
            //主键
            productVo.setSameId(product.getId());
            //产品数量
            BigDecimal productNum = new BigDecimal("0");
            if(StringUtil.isNotEmpty(product.getProductNum())){
                productNum = product.getProductNum();
            }
            //实际数量
            BigDecimal stockNum = new BigDecimal("0");
            if(StringUtil.isNotEmpty(product.getStockNum())){
                stockNum = product.getStockNum();
            }
            //出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(product.getOutWarehouseApply())){
                outWarehouseApply = product.getOutWarehouseApply();
            }
            //剩余可出库数量
            BigDecimal lastNum = stockNum.subtract(outWarehouseApply);
            //可申请数量
            BigDecimal canApplyQuantity = product.getCanApplyQuantity();
            BigDecimal tempNum = new BigDecimal("0");
            if(lastNum.compareTo(canApplyQuantity) == 1){
                //取两者最小数量
                tempNum = tempNum.add(canApplyQuantity);
            }else {
                tempNum = tempNum.add(lastNum);
            }
            if(productNum.compareTo(tempNum) == 1){
                //剩余数量
                productVo.setTheRemainingAmount(tempNum);
                //出库数量,默认等于剩余数量
                productVo.setOutStockQuantity(tempNum);
            }else {
                //剩余数量
                productVo.setTheRemainingAmount(productNum);
                //出库数量,默认等于剩余数量
                productVo.setOutStockQuantity(productNum);
            }

            productVos.add(productVo);
        }
        return productVos;
    }

    /**
     * 新增、修改
     * @param req 新增、修改入参
     * @param creator 创建人
     * @param createNo 创建人编码
     * @return 新增、修改结果
     */
    @Transactional(rollbackFor = Exception.class)
    public R add(SellOutStockAddReq req, String creator, String createNo) throws ParseException {
        //一：单号唯一性校验
        boolean billNoCheckFlag = (null != req.getId() && req.getBillNo().equals(req.getNewBillNo()));
        if(!billNoCheckFlag){
            //单号做唯一校验
            boolean billNoFlag = checkRepeatBillNo(req.getBillNo());
            if(!billNoFlag){
                return R.buildError(ResultStatusEnum.BILL_NO_REPEAT);
            }
        }

        //销售出库校验
        if(!checkIsSellOutStock(req)){
            return R.buildError(ResultStatusEnum.OUT_STOCK_QUANTITY_CHECK_ERROR);
        }

        //二：主表新增
        Integer id = insert(req, creator, createNo);
        if(id == null){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }

        //三：明细新增
        insertDetail(req, id, creator, createNo);

        //四：添加附件信息
        boolean flag = addAnnex(req.getAnnexList(), id, creator, createNo);
        if(!flag){
            LOGGER.info("出口业务-报价-批量新增附件异常");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //删除临时附件信息
        deleteTempAnnex(req.getAnnexList());

        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 校验是否可以销售出库 true:是 false:否
     * @param req 出口参数
     * @return 否可以销售出库 true:是 false:否
     */
    private boolean checkIsSellOutStock(SellOutStockAddReq req){
        List<SellOutStockDetailAddReq> detailList = req.getDetailList();
        if(CollectionUtils.isEmpty(detailList)){
            return false;
        }
        for(SellOutStockDetailAddReq detail : detailList){
            //获取库存id
            Integer stockId = detail.getStockId();
            if(null == stockId){
                return false;
            }
            //获取本次出库数量
            BigDecimal outStockQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(detail.getOutStockQuantity())){
                outStockQuantity = detail.getOutStockQuantity();
            }
            //获取库存信息
            StockEntity stock = stockService.getStockById(stockId);
            //获取出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getOutWarehouseApply())){
                outWarehouseApply = stock.getOutWarehouseApply();
            }
            //获取实际数量
            BigDecimal realQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getRealQuantity())){
                realQuantity = stock.getRealQuantity();
            }

            if(null == req.getId()){
                //新增
                //校验：剩余数量（实际数量-出库申请数量）- 本次出库数量 大于等于零
                //剩余数量
                BigDecimal lastQuantity = realQuantity.subtract(outWarehouseApply);
                BigDecimal quantity = lastQuantity.subtract(outStockQuantity);
                //如果库存剩余数量-本次出库数量小于零，则不能库出
                if(quantity.compareTo(BigDecimal.ZERO) == -1){
                    return false;
                }
            }else {
                //修改
                if(null == req.getStatus()){
                    return false;
                }
                //获取修改前单据信息
                SellOutStockDetailEntity detailEntity = sellOutStockDetailService.queryById(detail.getId());
                //获取修改前出库数量
                BigDecimal oldOutStockQuantity = new BigDecimal("0");
                if(StringUtil.isNotEmpty(detailEntity.getOutStockQuantity())){
                    oldOutStockQuantity = detailEntity.getOutStockQuantity();
                }
                if(req.getStatus() == OperationStatusEnum.DRAFT_BOX.getId()){
                    //草稿箱修改
                    //校验：剩余数量（实际数量-出库申请数量-修改前出库数量）- 本次出库数量 大于等于零
                    BigDecimal lastQuantity = realQuantity.subtract(outWarehouseApply).subtract(oldOutStockQuantity);
                    BigDecimal quantity = lastQuantity.subtract(outStockQuantity);
                    //如果库存剩余数量-本次出库数量小于零，则不能库出
                    if(quantity.compareTo(BigDecimal.ZERO) == -1){
                        return false;
                    }
                }else if(req.getStatus() == OperationStatusEnum.APPROVED_BOX.getId()){
                    //已批箱修改
                    //校验：剩余数量（新实际数量-出库申请数量）- 本次出库数量 大于等于零

                    //新实际数量 = 实际数量+修改前出库数量
                    BigDecimal newRealQuantity = realQuantity.add(oldOutStockQuantity);
                    //剩余数量
                    BigDecimal lastQuantity = newRealQuantity.subtract(outWarehouseApply);

                    BigDecimal quantity = lastQuantity.subtract(outStockQuantity);
                    //如果库存剩余数量-本次出库数量小于零，则不能库出
                    if(quantity.compareTo(BigDecimal.ZERO) == -1){
                        return false;
                    }
                }
            }

        }
        return true;
    }

    /**
     * 审批
     * @param transferId 出库id
     * @return 审批结果
     */
    private R checkTransfer(Integer transferId){
        //通过id获取调拨对象
        SellOutStockEntity transfer = sellOutStockService.queryById(transferId);
        if(null == transfer){
            LOGGER.warn("仓库管理-其它出库-审核-获取出库对象为空");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //初始化调拨明细对象
        SellOutStockDetailEntity transferDetailReq = new SellOutStockDetailEntity();
        //设置id
        transferDetailReq.setParentId(transferId);
        //设置数据有效性(0:无效 1:有效)
        transferDetailReq.setValid(DataIsValidEnum.VALID.getId());
        //查询调拨明细
        List<SellOutStockDetailEntity> transferDetails = sellOutStockDetailService.queryAll(transferDetailReq);
        if(CollectionUtils.isEmpty(transferDetails)){
            LOGGER.warn("仓库管理-其它出库-审核-获取出库明细对象为空");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        for(SellOutStockDetailEntity transferDetail : transferDetails){
            //获取库存id
            Integer stockId = transferDetail.getStockId();
            //通过库存id获取库存信息
            StockEntity stockEntity = stockService.getStockById(stockId);
            //初始化库存对象
            StockEntity stock = new StockEntity();
            //设置库存id
            stock.setId(stockId);

            //原实际数量
            BigDecimal realQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stockEntity.getRealQuantity())){
                realQuantity = stockEntity.getRealQuantity();
            }
            //出库数量
            BigDecimal transferQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(transferDetail.getOutStockQuantity())){
                transferQuantity = transferDetail.getOutStockQuantity();
            }
            BigDecimal quantity = realQuantity.subtract(transferQuantity);
            //更新实际数量
            stock.setRealQuantity(quantity);
            //更新实际可用数量
            stock.setRealAvailableQuantity(quantity);
            //可申请数量
            BigDecimal canApplyQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stockEntity.getCanApplyQuantity())){
                canApplyQuantity = stockEntity.getCanApplyQuantity();
            }
            stock.setCanApplyQuantity(canApplyQuantity.subtract(transferQuantity));
            //调用库存接口更新库存信息
            stockService.update(stock);

            //原库存新增明细(出库流水)
            insertStockDetail(transferQuantity, transfer, stockEntity);
        }
        //修改状态,改为完成箱
        SellOutStockEntity transferEntity = new SellOutStockEntity();
        transferEntity.setId(transferId);
        transferEntity.setStatus(OperationStatusEnum.APPROVED_BOX.getId());
        sellOutStockService.update(transferEntity);

        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 审批后库存明细新增
     * @param num 出库数量
     * @param transfer 出库对象
     * @param stock 库存对象
     */
    private void insertStockDetail(BigDecimal num, SellOutStockEntity transfer, StockEntity stock){
        StockDetailEntity stockDetail = new StockDetailEntity();
        //库存id
        stockDetail.setStockId(stock.getId());
        //标题
        stockDetail.setTitle(DataSourceTitleEnum.SELL_OUT_STOCK.getDesc());
        //模块id
        stockDetail.setModuleId(DataSourceTitleEnum.SELL_OUT_STOCK.getId());
        //单据编号(调拨单号)
        stockDetail.setInvoiceNumber(transfer.getBillNo());
        //产品编码
        stockDetail.setProductCode(stock.getProductCode());
        //规格编码
        stockDetail.setSpecificationCode(stock.getSpecificationCode());
        //颜色
        stockDetail.setColor(stock.getColor());
        //成本单价(初始来源于备货入库中的 入库成本)
        BigDecimal productUnitPrice = stock.getProductUnitPrice();
        stockDetail.setUnitPrice(productUnitPrice);
        //成本金额=成本单价*实际数量
        if(StringUtil.isNotEmpty(productUnitPrice) && StringUtil.isNotEmpty(num)){
            stockDetail.setMoney(productUnitPrice.multiply(num));
        }
        //数量
        stockDetail.setQuantity(num);
        //标准单位数量
        stockDetail.setStandardUnitQuantity(num);
        //标准单位
        stockDetail.setStandardUnit(stock.getProductUnit());
        //创建时间
        stockDetail.setCreateDate(new Date());
        //出库人
        stockDetail.setInStorePerson(transfer.getOutPerson());
        //出库人编码
        stockDetail.setInStoreCode(transfer.getOutPersonCode());
        //操作人
        stockDetail.setOperator(transfer.getOperation());
        //操作人编码
        stockDetail.setOperationCode(transfer.getOperationCode());
        //规格说明
        stockDetail.setProductSpecExplanation(stock.getSpecificationExplanation());
        //备注
        stockDetail.setMemo(transfer.getMemo());
        //数据有效
        stockDetail.setValid(DataIsValidEnum.VALID.getId());

        //调用库存明细接口新增库存明细
        stockDetailService.insert(stockDetail);
    }

    /**
     * 批量处理临时附件信息，将临时附件设置为失效
     * @param annexReqs
     */
    private void deleteTempAnnex(List<AnnexReq> annexReqs){
        //没有附件
        if(CollectionUtils.isEmpty(annexReqs)){
            return;
        }
        //存在附件
        for(AnnexReq annex : annexReqs){
            if(null != annex.getNews()){
                //旧附件,不用修改
                continue;
            }
            TempAnnexEntity tempAnnex = new TempAnnexEntity();
            //设置临时附件id
            tempAnnex.setId(annex.getId());
            //设置修改时间
            tempAnnex.setUpdateTime(new Date());
            //将附件设置为失效
            tempAnnex.setValid(0);
            tempAnnexService.update(tempAnnex);
        }

    }

    /**
     * 附件新增
     * @param annexReqs 附件信息
     * @param id 付款id
     * @param operator 操作人
     * @param operatorNo 操作人编码
     * @return 是否新增成功(true:成功 false:失败 )
     */
    private boolean addAnnex(List<AnnexReq> annexReqs, Integer id, String operator, String operatorNo) {
        try {
            //没有附件,将该id关联的所有附件设为无效
            if(CollectionUtils.isEmpty(annexReqs)){
                AnnexEntity annexReq = new AnnexEntity();
                annexReq.setParentId(id);
                annexReq.setModuleId(ModuleTypeEnum.WAREHOUSE_SALES_OUT_STOCK.getId());
                List<AnnexEntity> annexList = annexService.queryAll(annexReq);
                if(!CollectionUtils.isEmpty(annexList)){
                    for(AnnexEntity annex : annexList){
                        AnnexEntity updateAnnex= new AnnexEntity();
                        updateAnnex.setId(annex.getId());
                        //将被删除的附件设为失效
                        updateAnnex.setValid(DataIsValidEnum.INVALID.getId());
                        annexService.update(updateAnnex);
                    }
                }
                return true;
            }
            //存在附件,新增附件信息
            List<AnnexEntity> list = new ArrayList<>();
            //获取旧的附件id集合
            List<Integer> oldIds = new ArrayList<>();
            for(AnnexReq annexReq : annexReqs){
                if(null != annexReq.getNews()){
                    //属于旧附件 只取id,不新增
                    oldIds.add(annexReq.getId());
                    continue;
                }
                AnnexEntity annex = new AnnexEntity();
                BeanUtils.copyProperties(annexReq, annex);
                //设置关联模块id
                annex.setModuleId(ModuleTypeEnum.WAREHOUSE_SALES_OUT_STOCK.getId());
                //设置关联模块父id
                annex.setParentId(id);
                //设置上传时间
                annex.setUploadTime(DateUtils.convertStringToDate(annexReq.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置修改时间
                annex.setUpdateTime(new Date());
                //设置操作人
                annex.setOperator(operator);
                //设置操作人编码
                annex.setOperatorNo(operatorNo);
                //设置数据有效
                annex.setValid(1);

                list.add(annex);
            }
            if(oldIds.size() > 0){
                //通过调拨id获取修改附件信息
                AnnexEntity annex = new AnnexEntity();
                annex.setModuleId(ModuleTypeEnum.WAREHOUSE_SALES_OUT_STOCK.getId());
                annex.setParentId(id);
                //获取上次附件信息
                List<AnnexEntity> annexList = annexService.queryAll(annex);
                if(!CollectionUtils.isEmpty(annexList)){
                    //获取上次附件id集合
                    List<Integer> oldAnnexIds = annexList.stream().map(p -> p.getId()).collect(Collectors.toList());
                    //得到被删除的附件id
                    Collection collection = new ArrayList(oldAnnexIds);
                    collection.removeAll(oldIds);
                    if(collection.size() > 0){
                        Iterator<Integer> it = collection.iterator();
                        while (it.hasNext()){
                            int detailId = it.next();
                            AnnexEntity annexEntity = new AnnexEntity();
                            annexEntity.setId(detailId);
                            //将被删除的附件设为失效
                            annexEntity.setValid(DataIsValidEnum.INVALID.getId());

                            annexService.update(annexEntity);
                        }
                    }
                }
            }
            if(!CollectionUtils.isEmpty(list)){
                //附件批量新增
                int res = annexService.batchInsert(list);
                if(res == list.size()){
                    return true;
                }
            }
            return true;
        }catch (Exception e){
            throw new RuntimeException();
        }
    }

    /**
     * 明细新增
     * @param req 新增对象
     * @param id id
     */
    public void insertDetail(SellOutStockAddReq req, int id, String creator, String createNo) {
        if(!CollectionUtils.isEmpty(req.getDetailList())){
            //库存数据修改
            updateStockInfo(req);
            //获取修改调拨明细id集合
            List<Integer> newIds = new ArrayList<>();
            //新增调拨明细集合
            List<SellOutStockDetailEntity> addTransferDetails = new ArrayList<>();
            for(SellOutStockDetailAddReq detailReq : req.getDetailList()){
                //初始化调拨明细对象
                SellOutStockDetailEntity transferDetail = new SellOutStockDetailEntity();
                //赋值
                BeanUtils.copyProperties(detailReq, transferDetail);
                //设置id
                transferDetail.setParentId(id);
                //设置数据有效性(0:无效 1:有效)
                transferDetail.setValid(DataIsValidEnum.VALID.getId());

                //库存明细新增
                int stockDetailId = addStockDetail(detailReq, req.getBillNo(), creator, createNo);


                if(null == detailReq.getId()){
                    //新增
                    //设置明细库存id
                    transferDetail.setStockDetailId(stockDetailId);
                    addTransferDetails.add(transferDetail);
                }else {
                    //修改
                    //获取明细id
                    newIds.add(detailReq.getId());
                    sellOutStockDetailService.update(transferDetail);
                }

            }

            //处理被删除的调拨明细
            handleBeenDeletedTransferDetail(req, id, newIds);

            if(!CollectionUtils.isEmpty(addTransferDetails)){
                //调用接口保存明细
                sellOutStockDetailService.addList(addTransferDetails);
            }
        }
    }

    /**
     * 修改库存信息
     * @param req 修改对象
     */
    private void updateStockInfo(SellOutStockAddReq req){
        List<SellOutStockDetailAddReq> detailList = req.getDetailList();
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        for(SellOutStockDetailAddReq detail : detailList){
            //获取库存id
            Integer stockId = detail.getStockId();
            if(null == stockId){
                return;
            }
            //获取本次出库数量
            BigDecimal outStockQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(detail.getOutStockQuantity())){
                outStockQuantity = detail.getOutStockQuantity();
            }
            //获取库存信息
            StockEntity stock = stockService.getStockById(stockId);
            //获取出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getOutWarehouseApply())){
                outWarehouseApply = stock.getOutWarehouseApply();
            }
            //获取实际数量
            BigDecimal realQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getRealQuantity())){
                realQuantity = stock.getRealQuantity();
            }
            //可申请数量
            BigDecimal canApplyQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getCanApplyQuantity())){
                canApplyQuantity = stock.getCanApplyQuantity();
            }

            if(null == req.getId()){
                //新增
                //1.保存到草稿箱：库存实际数量不变 新出库申请数量 = 本次出库数量+出库申请数量
                //新出库申请数量
                BigDecimal newOutWarehouseApply = outStockQuantity.add(outWarehouseApply);
                stock.setOutWarehouseApply(newOutWarehouseApply);
                //2.新的可申请数量 = 老的可申请数量 - 出库数量
                BigDecimal newCanApplyQuantity = canApplyQuantity.subtract(outStockQuantity);
                stock.setCanApplyQuantity(newCanApplyQuantity);
            }else {
                //修改
                if(null == req.getStatus()){
                    return;
                }
                //获取修改前单据信息
                SellOutStockDetailEntity detailEntity = sellOutStockDetailService.queryById(detail.getId());
                //获取修改前出库数量
                BigDecimal oldOutStockQuantity = new BigDecimal("0");
                if(StringUtil.isNotEmpty(detailEntity.getOutStockQuantity())){
                    oldOutStockQuantity = detailEntity.getOutStockQuantity();
                }

                if(req.getStatus() == OperationStatusEnum.DRAFT_BOX.getId()){
                    //草稿箱修改:保存到草稿箱
                    //库存实际数量不变 新出库申请数量 = 本次出库数量+（出库申请数量-修改前出库数量）
                    //出库申请数量-修改前出库数量
                    BigDecimal quantity = outWarehouseApply.subtract(oldOutStockQuantity);
                    //新出库申请数量 = 本次出库数量+（出库申请数量-修改前出库数量）
                    BigDecimal newOutWarehouseApply = outStockQuantity.add(quantity);
                    stock.setOutWarehouseApply(newOutWarehouseApply);
                }else if(req.getStatus() == OperationStatusEnum.APPROVED_BOX.getId()){
                    //已批箱修改:保存到草稿箱
                    //新实际数量 = 实际数量+修改前出库数量
                    BigDecimal newRealQuantity = realQuantity.add(oldOutStockQuantity);
                    stock.setRealQuantity(newRealQuantity);

                    //新出库申请数量 = 出库申请数量+本次出库数量
                    BigDecimal newOutWarehouseApply = outWarehouseApply.add(outStockQuantity);
                    stock.setOutWarehouseApply(newOutWarehouseApply);
                }

                //差值 = 本次出库数量 - 修改前出库数量
                BigDecimal subNum = outStockQuantity.subtract(oldOutStockQuantity);
                //新可申请数量 = 老的可申请数量 - 差值
                BigDecimal newCanApplyQuantity = canApplyQuantity.subtract(subNum);
                stock.setCanApplyQuantity(newCanApplyQuantity);
            }
            //调用库存接口保存新的出库数量
            stockService.update(stock);
        }

    }

    /**
     * 处理被删除的明细
     * @param req 明细
     * @param pid pid
     * @param newIds 修改后未被删除的明细id集合
     */
    private void handleBeenDeletedTransferDetail(SellOutStockAddReq req, int pid, List<Integer> newIds){
        if(null != req.getId()){
            //修改-找出被删除的明细

            SellOutStockDetailEntity transferDetail = new SellOutStockDetailEntity();
            //设置id
            transferDetail.setParentId(pid);
            //查询有效数据
            transferDetail.setValid(DataIsValidEnum.VALID.getId());
            //调用接口查询结果
            List<SellOutStockDetailEntity> transferDetails = sellOutStockDetailService.queryAll(transferDetail);
            if(!CollectionUtils.isEmpty(transferDetails)){
                //获取明细id和库存明细id
                Map<String, Map<Integer, Integer>> stockIdAndStockDetailIdMap = getStockIdAndStockDetailIdMap(transferDetails);
                //获取调拨数量
                Map<Integer, BigDecimal> transferQuantityMap = getTransferQuantityMap(transferDetails);
                //获取id集合
                List<Integer> oldIds = transferDetails.stream().map(p -> p.getId()).collect(Collectors.toList());
                //找出被删除的id
                Collection collection = new ArrayList(oldIds);
                collection.removeAll(newIds);
                if(collection.size() > 0){
                    //遍历删除被删除的明细
                    Iterator<Integer> ids = collection.iterator();
                    while (ids.hasNext()){
                        int id = ids.next();
                        Integer stockId = stockIdAndStockDetailIdMap.get("stockIdMap").get(id);
                        //获取库存数据
                        StockEntity stock = stockService.getStockById(stockId);
                        //初始化库存对象
                        StockEntity stockReq = new StockEntity();
                        //设置修改主键
                        stockReq.setId(stockId);
                        //获取出库数量
                        BigDecimal transferQuantity = transferQuantityMap.get(id);
                        //删除的是已批数据,则需要回退 实际数量、可申请数量
                        stockReq.setRealQuantity(stock.getRealQuantity().add(transferQuantity));
                        stockReq.setRealAvailableQuantity(stock.getRealAvailableQuantity().add(transferQuantity));
                        stockReq.setCanApplyQuantity(stock.getCanApplyQuantity().add(transferQuantity));
                        //回退删除的出库数量
                        stockService.update(stockReq);

                        SellOutStockDetailEntity detail = new SellOutStockDetailEntity();
                        detail.setId(id);
                        detail.setValid(DataIsValidEnum.INVALID.getId());
                        //将删除的明细设为无效
                        sellOutStockDetailService.update(detail);
                        //通过明细id获取库存库存明细id
                        Integer stockDetailId = stockIdAndStockDetailIdMap.get("stockDetailIdMap").get(id);
                        //将库存明细设为无效
                        StockDetailEntity stockDetail = new StockDetailEntity();
                        stockDetail.setId(stockDetailId);
                        stockDetail.setValid(DataIsValidEnum.INVALID.getId());
                        stockDetailService.update(stockDetail);
                    }
                }
            }
        }
    }

    /**
     * 获取库存id和库存明细id
     * @param transferDetails 明细对象
     * @return key为明细id value为库存id和库存明细id
     */
    private Map<String, Map<Integer, Integer>> getStockIdAndStockDetailIdMap(List<SellOutStockDetailEntity> transferDetails){
        //获取集合大小
        int size = transferDetails.size();
        //库存明细id
        Map<Integer, Integer> stockDetailIdMap = new HashMap<>(size);
        //库存id
        Map<Integer, Integer> stockIdMap = new HashMap<>(size);
        for(SellOutStockDetailEntity transferDetail : transferDetails){
            stockDetailIdMap.put(transferDetail.getId(), transferDetail.getStockDetailId());
            stockIdMap.put(transferDetail.getId(), transferDetail.getStockId());
        }
        Map<String, Map<Integer, Integer>> map = new HashMap<>(3);
        map.put("stockDetailIdMap", stockDetailIdMap);
        map.put("stockIdMap", stockIdMap);
        return map;
    }

    /**
     * 获取出库数量
     * @param transferDetails 出库明细对象
     * @return key为明细id value为出库数量
     */
    private Map<Integer, BigDecimal> getTransferQuantityMap(List<SellOutStockDetailEntity> transferDetails){
        //调拨数量
        Map<Integer, BigDecimal> transferQuantityMap = new HashMap<>(transferDetails.size());
        for(SellOutStockDetailEntity transferDetail : transferDetails){
            transferQuantityMap.put(transferDetail.getId(), transferDetail.getOutStockQuantity());
        }
        return transferQuantityMap;
    }

    /**
     * 新增库存明细
     * @param detailReq 明细
     * @param billNo 单号
     * @param creator 创建人
     * @param createNo 创建人编码
     */
    private int addStockDetail(SellOutStockDetailAddReq detailReq, String billNo, String creator, String createNo){
        //初始化库存明细对象
        StockDetailEntity stockDetail = new StockDetailEntity();
        //赋值
        BeanUtils.copyProperties(detailReq, stockDetail);
        //设置标题
        stockDetail.setTitle(DataSourceTitleEnum.SELL_OUT_STOCK.getDesc());
        //设置单据编号
        stockDetail.setInvoiceNumber(billNo);
        //设置单价
        stockDetail.setUnitPrice(detailReq.getFcUnitPrice());
        //设置数量
        stockDetail.setQuantity(detailReq.getOutStockQuantity());
        //设置模块id
        stockDetail.setModuleId(ModuleTypeEnum.WAREHOUSE_SALES_OUT_STOCK.getId());
        //设置创建人
        stockDetail.setInStorePerson(creator);
        //设置创建人编码
        stockDetail.setInStoreCode(createNo);
        //设置操作人
        stockDetail.setOperator(creator);
        //设置操作人编码
        stockDetail.setOperationCode(createNo);
        if(null == detailReq.getId()){
            //新增

            //设置创建时间
            stockDetail.setCreateDate(new Date());
            //设置有效性
            stockDetail.setValid(DataIsValidEnum.VALID.getId());
            stockDetailService.insert(stockDetail);

        }else {
            //修改

            stockDetail.setId(detailReq.getStockDetailId());
            stockDetailService.update(stockDetail);
        }

        return stockDetail.getId();
    }

    /**
     * 新增主表信息
     * @param req 新增参数
     * @param creator 创建人
     * @param createNo 创建人编码
     * @return 主表id
     * @throws ParseException
     */
    private Integer insert(SellOutStockAddReq req, String creator, String createNo) throws ParseException {
        //初始化对象
        SellOutStockEntity sell = new SellOutStockEntity();
        //赋值
        BeanUtils.copyProperties(req, sell);
        //出库日期
        sell.setTime(DateUtils.convertStringToDate(req.getTime(), DateUtils.DATE_PATTERN));
        //提货日期
        sell.setPickUpDate(DateUtils.convertStringToDate(req.getPickUpDate(), DateUtils.DATE_PATTERN));
        //出库类型:销售出库
        sell.setType(OutStockTypeEnum.SALES_OUT_STOCK.getId());
        //保存后进草稿箱
        sell.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
        //设置数据有效性(0:无效 1:有效)
        sell.setValid(DataIsValidEnum.VALID.getId());

        if(null == req.getId()){
            //新增
            //设置创建时间
            sell.setCreateDate(new Date());
            //设置创建人
            sell.setOperation(creator);
            //设置创建人编码
            sell.setOperationCode(createNo);
            //调用接口新增调拨
            return sellOutStockService.insert(sell) == 1 ? sell.getId() : null;
        }else {
            //修改
            //设置修改时间
            sell.setModifyTime(new Date());
            return sellOutStockService.update(sell) == 1 ? sell.getId() : null;
        }

    }

    /**
     * 校验单号是否存在
     * @param billNo 单号
     * @return true:不重复 false:重复
     */
    private boolean checkRepeatBillNo(String billNo){
        SellOutStockEntity req = new SellOutStockEntity();
        req.setBillNo(billNo);
        req.setValid(DataIsValidEnum.VALID.getId());
        List<SellOutStockEntity> list = sellOutStockService.queryAll(req);
        if(CollectionUtils.isEmpty(list)){
            return true;
        }
        return false;
    }

    /**
     * 详情
     * @param id id
     * @return 详情
     */
    public SellOutStockVo detail(Integer id){
        //初始化回参对象
        SellOutStockVo vo = new SellOutStockVo();
        if(null == id){
            return vo;
        }
        //第一步：获取主表信息
        SellOutStockEntity offer = sellOutStockService.queryById(id);
        if(null == offer || null == offer.getId()){
            return vo;
        }
        //赋值
        BeanUtils.copyProperties(offer, vo);
        //设置出库时间
        vo.setTime(DateUtils.format(offer.getTime()));
        //提货日期
        vo.setPickUpDate(DateUtils.format(offer.getPickUpDate()));

        //第二步：获取产品明细数据
        SellOutStockDetailEntity offerDetailReq = new SellOutStockDetailEntity();
        //父id
        offerDetailReq.setParentId(id);
        //有效数据
        offerDetailReq.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询产品明细数据
        List<SellOutStockDetailEntity> offerDetailList = sellOutStockDetailService.queryAll(offerDetailReq);
        if(!CollectionUtils.isEmpty(offerDetailList)){
            //初始化回参对象集合
            List<SellOutStockDetailVo> detailList = new ArrayList<>();
            for(SellOutStockDetailEntity detailEntity : offerDetailList){
                //初始化回参对象
                SellOutStockDetailVo productDetailVo = new SellOutStockDetailVo();
                //赋值
                BeanUtils.copyProperties(detailEntity, productDetailVo);

                detailList.add(productDetailVo);
            }
            //添加产品明细数据
            vo.setDetailList(detailList);
        }

        //获取对应附件信息
        getAnnexDetail(id, vo);

        return vo;
    }

    /**
     * 获取附件详情
     * @param id 销售出库id
     * @param vo 回参实体
     */
    private void getAnnexDetail(Integer id, SellOutStockVo vo) {
        AnnexEntity annex = new AnnexEntity();
        //设置模块id
        annex.setModuleId(ModuleTypeEnum.WAREHOUSE_SALES_OUT_STOCK.getId());
        //设置父id
        annex.setParentId(id);
        //设置数据有效
        annex.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询附件信息
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if (CollectionUtils.isEmpty(annexList)) {
            return;
        }
        List<AnnexVo> annexVos = annexList.stream().map(p -> {
            AnnexVo annexVo = new AnnexVo();
            //赋值
            BeanUtils.copyProperties(p, annexVo);
            //上传时间转换
            annexVo.setUploadTime(DateUtils.format(p.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
            //设置附件为旧附件,用以区分修改时附件状态
            annexVo.setNews(0);

            return annexVo;
        }).collect(Collectors.toList());

        vo.setAnnexList(annexVos);
    }

    /**
     * 删除
     * @param req 操作对象
     */
    public void delete(OperationReq req){
        if(null == req.getId() || null == req.getStatus()){
            return;
        }
        SellOutStockEntity queryReq = new SellOutStockEntity();
        queryReq.setId(req.getId());
        queryReq.setModifyTime(new Date());
        if(req.getStatus().equals(OperationStatusEnum.DRAFT_BOX.getId())){
            //草稿箱删除,数位改为垃圾箱
            queryReq.setStatus(OperationStatusEnum.TRASH_CAN.getId());
            sellOutStockService.update(queryReq);
            //库存 新出库申请数量 = 出库申请数量 - 出库数量
            updateTrashCanStock(req.getId());
            return;
        }else {
            //垃圾箱删除,将主数据设为无效
            queryReq.setValid(DataIsValidEnum.INVALID.getId());
            sellOutStockService.update(queryReq);
        }
        //获取对应明细数据
        SellOutStockDetailEntity detailEntity = new SellOutStockDetailEntity();
        detailEntity.setParentId(req.getId());
        detailEntity.setValid(DataIsValidEnum.VALID.getId());

        List<SellOutStockDetailEntity> detailList = sellOutStockDetailService.queryAll(detailEntity);
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        //将所有对应有效的明细数据设为无效
        for(SellOutStockDetailEntity detail : detailList){
            SellOutStockDetailEntity detailReq = new SellOutStockDetailEntity();
            detailReq.setId(detail.getId());
            detailReq.setValid(DataIsValidEnum.INVALID.getId());

            sellOutStockDetailService.update(detailReq);
        }

        //获取对应所有附件
        AnnexEntity annex = new AnnexEntity();
        annex.setModuleId(ModuleTypeEnum.WAREHOUSE_SALES_OUT_STOCK.getId());
        annex.setParentId(req.getId());
        annex.setValid(DataIsValidEnum.VALID.getId());
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if(CollectionUtils.isEmpty(annexList)){
            return;
        }
        //删除所有对应的有效的附件
        for(AnnexEntity annexData : annexList){
            AnnexEntity annexReq = new AnnexEntity();
            annexReq.setId(annexData.getId());
            annexReq.setUpdateTime(new Date());
            annexReq.setValid(DataIsValidEnum.INVALID.getId());

            annexService.update(annexReq);
        }
    }

    /**
     * 垃圾箱:更新库存信息
     * @param id 销售出库id
     */
    private void updateTrashCanStock(Integer id){
        //库存 新出库申请数量 = 出库申请数量 - 出库数量
        //获取销售库存明细
        SellOutStockDetailEntity req = new SellOutStockDetailEntity();
        req.setParentId(id);
        req.setValid(DataIsValidEnum.VALID.getId());
        List<SellOutStockDetailEntity> detailList = sellOutStockDetailService.queryAll(req);
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        for(SellOutStockDetailEntity detail : detailList){
            //获取出库数量
            BigDecimal outStockQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(detail.getOutStockQuantity())){
                outStockQuantity = detail.getOutStockQuantity();
            }

            //获取库存明细
            StockEntity stock = stockService.getStockById(detail.getStockId());

            //获取出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getOutWarehouseApply())){
                outWarehouseApply = stock.getOutWarehouseApply();
            }

            //新出库申请数量 = 出库申请数量 - 出库数量
            BigDecimal newOutWarehouseApply = outWarehouseApply.subtract(outStockQuantity);
            stock.setOutWarehouseApply(newOutWarehouseApply);

            //更新库存信息
            stockService.update(stock);
        }

    }

    /**
     * 箱体操作
     * @param req 操作对象
     */
    public R operation(OperationReq req){
        if(null == req.getId() || null == req.getOperation() || StringUtils.isBlank(req.getBillNo())){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        SellOutStockEntity offerEntity = new SellOutStockEntity();
        //设置修改主键
        offerEntity.setId(req.getId());
        //修改时间
        offerEntity.setModifyTime(new Date());

        switch (req.getOperation()){
            case 1:
                //提交审批后,状态设为已批箱
                offerEntity.setStatus(OperationStatusEnum.APPROVED_BOX.getId());
                updateApprovedBoxStock(req.getId());
                //修改库存信息
                break;
            case 2:
                //审批通过
                break;
            case 3:
                //审批退回
                break;
            case 4:
                //将状态设为完成
                offerEntity.setStatus(OperationStatusEnum.COMPLETION_BOX.getId());
                break;
            case 5:
                //点击还原，将状态改为草稿箱
                offerEntity.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
                //更新库存信息：新出库申请数量 = 出库申请数量 + 出库数量
                updateDraftBoxStock(req.getId());
                break;
        }
        //调用接口修改
        sellOutStockService.update(offerEntity);
        return R.buildError(ResultStatusEnum.SUCCESS);
    }

    /**
     * 草稿箱:更新库存信息
     * @param id 销售出库id
     */
    private void updateDraftBoxStock(Integer id){
        //获取销售库存明细
        SellOutStockDetailEntity req = new SellOutStockDetailEntity();
        req.setParentId(id);
        req.setValid(DataIsValidEnum.VALID.getId());
        List<SellOutStockDetailEntity> detailList = sellOutStockDetailService.queryAll(req);
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        for(SellOutStockDetailEntity detail : detailList){
            //获取出库数量
            BigDecimal outStockQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(detail.getOutStockQuantity())){
                outStockQuantity = detail.getOutStockQuantity();
            }

            //获取库存明细
            StockEntity stock = stockService.getStockById(detail.getStockId());

            //获取出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getOutWarehouseApply())){
                outWarehouseApply = stock.getOutWarehouseApply();
            }

            //新出库申请数量 = 出库申请数量 + 出库数量
            BigDecimal newOutWarehouseApply = outWarehouseApply.add(outStockQuantity);
            stock.setOutWarehouseApply(newOutWarehouseApply);

            //更新库存信息
            stockService.update(stock);
        }

    }

    /**
     * 已批箱:更新库存信息
     * @param id 销售出库id
     */
    private void updateApprovedBoxStock(Integer id){
        //获取销售库存明细
        SellOutStockDetailEntity req = new SellOutStockDetailEntity();
        req.setParentId(id);
        req.setValid(DataIsValidEnum.VALID.getId());
        List<SellOutStockDetailEntity> detailList = sellOutStockDetailService.queryAll(req);
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        for(SellOutStockDetailEntity detail : detailList){
            //获取出库数量
            BigDecimal outStockQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(detail.getOutStockQuantity())){
                outStockQuantity = detail.getOutStockQuantity();
            }

            //获取库存明细
            StockEntity stock = stockService.getStockById(detail.getStockId());

            //获取实际数量
            BigDecimal realQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getRealQuantity())){
                realQuantity = stock.getRealQuantity();
            }

            //获取出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getOutWarehouseApply())){
                outWarehouseApply = stock.getOutWarehouseApply();
            }

            //新的实际数量 = 实际数量-出库数量
            BigDecimal newRealQuantity = realQuantity.subtract(outStockQuantity);
            stock.setRealQuantity(newRealQuantity);

            //新出库申请数量 = 出库申请数量 - 出库数量
            BigDecimal newOutWarehouseApply = outWarehouseApply.subtract(outStockQuantity);
            stock.setOutWarehouseApply(newOutWarehouseApply);

            //更新库存信息
            stockService.update(stock);
        }

    }



    /**
     * 是否成功回退数据
     * @param id 出库id
     * @return 回退结果
     */
    private boolean checkDataIsRollBack(Integer id){
        SellOutStockDetailEntity req = new SellOutStockDetailEntity();
        req.setParentId(id);
        req.setValid(DataIsValidEnum.VALID.getId());
        List<SellOutStockDetailEntity> detailList = sellOutStockDetailService.queryAll(req);
        if(CollectionUtils.isEmpty(detailList)){
            return true;
        }
        for(SellOutStockDetailEntity detailEntity : detailList){
            //获取出库数量
            BigDecimal outStockQuantity = detailEntity.getOutStockQuantity();
            //获取库存明细
            StockEntity stock = stockService.getStockById(detailEntity.getStockId());
            //获取实际数量
            BigDecimal realQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getRealQuantity())){
                realQuantity = stock.getRealQuantity();
            }
            //回退实际数量
            stock.setRealQuantity(realQuantity.add(outStockQuantity));

            //获取实际可用数量
            BigDecimal realAvailableQuantity = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getRealAvailableQuantity())){
                realAvailableQuantity = stock.getRealAvailableQuantity();
            }
            //回退实际可用数量
            stock.setRealAvailableQuantity(realAvailableQuantity.add(outStockQuantity));

            //获取出库申请数量
            BigDecimal outWarehouseApply = new BigDecimal("0");
            if(StringUtil.isNotEmpty(stock.getOutWarehouseApply())){
                outWarehouseApply = stock.getOutWarehouseApply();
            }
            //回退出库申请数量
            stock.setOutWarehouseApply(outWarehouseApply.add(outStockQuantity));

            int flag = stockService.update(stock);
            if(0 == flag){
                return false;
            }
        }
        return true;
    }
    /**
     * 获取String类型不为空数据
     * @param value 目标数据
     * @return 不为空数据
     */
    private String getNotNullOfStringInfo(String value){
        if(StringUtils.isEmpty(value)){
            return "";
        }else {
            return value;
        }
    }

    /**
     * 获取BigDecimal类型不为空的数据
     * @param value 目标数据
     * @return 不为空数据
     */
    private BigDecimal getNotNullOfBigDecimalInfo(BigDecimal value){
        if(StringUtil.isNotEmpty(value)){
            return value;
        }else {
            return new BigDecimal("0");
        }
    }

    /**
     * 销售出库产品列表统计--集合
     * @param req
     * @return
     */
    public List<sellOutStockStatistics1Rsp> sellOutStockStatistics1RspList(sellOutStockStatistics1Req req){
        List<sellOutStockStatistics1Rsp> sellOutStockStatistics1RspList=sellOutStockService.sellOutStockStatistics1List(req);
        for (sellOutStockStatistics1Rsp p:sellOutStockStatistics1RspList) {
            p.setCreateDateStr(DateUtils.format(p.getCreateDate(),DateUtils.DATE_PATTERN));
            p.setPickUpDateStr(DateUtils.format(p.getPickUpDate(),DateUtils.DATE_PATTERN));
            p.setTimeStr(DateUtils.format(p.getTime(),DateUtils.DATE_PATTERN));

            //成本小计=出库成本*数量
            BigDecimal num=new BigDecimal(p.getOutStockQuantity());
            p.setCostSubtotal(p.getOutStockCost().multiply(num));

        }
        return sellOutStockStatistics1RspList;
    }
    /**
     * 销售出库产品列表统计--分页
     * @param req
     * @return
     */
    public PageInfo<sellOutStockStatistics1Rsp> sellOutStockStatistics1ListByPage(sellOutStockStatistics1Req req){
        List<sellOutStockStatistics1Rsp> sellOutStockStatistics1RspList=sellOutStockStatistics1RspList(req);
        PageInfo pageInfo=new PageInfo(sellOutStockStatistics1RspList);
        return  pageInfo;
    }

    /**
     * 入库通知统计-导出
     * @return
     */
    public JSONObject sellOutStockStatistics1Export(sellOutStockStatistics1Req req){
        List<sellOutStockStatistics1Rsp> sellOutStockStatistics1RspList=sellOutStockStatistics1RspList(req);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleSellOutStock();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if(CollectionUtils.isEmpty(sellOutStockStatistics1RspList)){
            obj.put("data", data);
            return obj;
        }
        excelSellOutStockExport(data,sellOutStockStatistics1RspList);
        obj.put("data", data);
        return obj;
    }
    public JSONArray getTitleSellOutStock(){
        JSONArray obj=new JSONArray();
        obj.add("序号");
        obj.add("出库单号");
        obj.add("出库日期");
        obj.add("出运计划号");
        obj.add("单位名称");
        obj.add("出库人");
        obj.add("创建时间");
        obj.add("提货日期");
        obj.add("产品编码");
        obj.add("规格编码");
        obj.add("销售合同号");
        obj.add("销售业务员");
        obj.add("客户合同号");
        obj.add("产品单位");
        obj.add("中文名称");
        obj.add("英文名称");
        obj.add("中文描述");
        obj.add("英文描述");
        obj.add("规格说明");
        obj.add("批次号");
        obj.add("出库数量");

        obj.add("销售单价");
        obj.add("金额小计");
        obj.add("出库成本");
        obj.add("成本小计");
        obj.add("出库产品成本");

//        obj.add("箱数");
//        obj.add("每箱数量");
//        obj.add("托盘入数");
//        obj.add("总托盘");
        return obj;
    }
    public void excelSellOutStockExport(JSONArray data,List<sellOutStockStatistics1Rsp> list ){
        //出库数量
        Integer outStockQuantity = 0;
        //箱数
        Integer boxAmount = 0;
        //每箱数量
        Integer everyBoxAmount = 0;
        //托盘入数
        Integer trayNumber = 0;
        //总托盘
        Integer totalTray = 0;
        //成本小计
        BigDecimal costSubtotal=new BigDecimal(0);
        Integer i=0;
        for (sellOutStockStatistics1Rsp vo: list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getBillNo()));
            infoList.add(getNotNullOfStringInfo(vo.getTimeStr()));
            infoList.add(getNotNullOfStringInfo(vo.getCarryPlanNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfStringInfo(vo.getOutPerson()));
            infoList.add(getNotNullOfStringInfo(vo.getCreateDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getPickUpDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecificationCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSaleContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getContractSalesmanName()));
            infoList.add(getNotNullOfStringInfo(vo.getClientContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getProductUnitName()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCname()));
            infoList.add(getNotNullOfStringInfo(vo.getProductEname()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCdesc()));
            infoList.add(getNotNullOfStringInfo(vo.getProductEdesc()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecificationExplanation()));
            infoList.add(getNotNullOfStringInfo(vo.getLotNo()));

            infoList.add(vo.getOutStockQuantity());


            infoList.add(getNotNullOfBigDecimalInfo(vo.getFcUnitPrice()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getMoneySubtotal()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getOutStockCost()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCostSubtotal()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductUnitPrice()));


//            infoList.add(vo.getBoxAmount());
//            infoList.add(vo.getEveryBoxAmount());
//            infoList.add(vo.getTrayNumber());
//            infoList.add(vo.getTotalTray());

            if(vo.getOutStockQuantity()!=null){
                outStockQuantity = outStockQuantity+vo.getOutStockQuantity();
            }
            if(vo.getBoxAmount()!=null){
                boxAmount = boxAmount+vo.getBoxAmount();
            }
            if(vo.getEveryBoxAmount()!=null){
                everyBoxAmount = everyBoxAmount+vo.getEveryBoxAmount();
            }
            if(vo.getTrayNumber()!=null){
                trayNumber = trayNumber+vo.getTrayNumber();
            }
            if(vo.getTotalTray()!=null){
                totalTray = totalTray+vo.getTotalTray();
            }
            if(vo.getCostSubtotal()!=null){
                costSubtotal = costSubtotal.add(vo.getCostSubtotal());
            }
            data.add(infoList);
        }
        //合计
        JSONArray infoList = new JSONArray();
        infoList.add("合计");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add("");


        infoList.add(outStockQuantity);
        infoList.add("");
        infoList.add("");
        infoList.add("");
        infoList.add(costSubtotal);
        infoList.add("");
//        infoList.add(boxAmount);
//        infoList.add(everyBoxAmount);
//        infoList.add(trayNumber);
//        infoList.add(totalTray);
        data.add(infoList);
    }



}
